package javaDemo.demo.day_05_03_FourFunctionalInterface;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @Description 分支合并框架
 * @Author
 * @Date 2020/11/8 16:39
 * @Version 1.0
 */
public class ForkJoinDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //线程操作资源类
        MyTask myTask = new MyTask(0, 100);

        //创建 ForkJoinPool 线程池
        ForkJoinPool threadPool = new ForkJoinPool();
        //通过 submit 方法将需要执行的任务提交；其返回值为 ForkJoinTask，里面封装了任务执行完的最终结果
        ForkJoinTask<Integer> forkJoinTask = threadPool.submit(myTask);
        //调用 get 方法即可获取到执行的返回结果
        System.out.println(forkJoinTask.get());

        //一定要记得关闭线程池
        threadPool.shutdown();
    }
}

//可以将一个大任务，先拆分成多个小任务去执行，最后将多个小任务的执行结果进行汇总
class MyTask extends RecursiveTask<Integer>{

    //定义任务拆分的最小量级
    private static final Integer ADJUST_VALUE = 10;

    //定义任务的 开始、结束、结果 变量
    private int begin;
    private int end;
    private int result;

    public MyTask(int begin,int end){
        this.begin = begin;
        this.end = end;
    }

    /**
     * 计算时，任务执行调用的方法
     * @return
     */
    @Override
    protected Integer compute() {
        //当前已经属于最小量级，直接计算处理即可
        if((end - begin) <= ADJUST_VALUE){
            for (int i = begin; i <= end ; i++) {
                result = result + i;
            }
        }else {
            //重新计算任务拆分的下一个边界
            int middle = (begin + end)/2;
            //当前还不是最小量级的，还需要拆分任务，先多线程的去执行，执行完后再统一汇总结果
            MyTask myTask1 = new MyTask(begin, middle);
            MyTask myTask2 = new MyTask(middle + 1, end);
            //调用 fork 方法，继续让子任务去递归调用 compute 方法
            myTask1.fork();
            myTask2.fork();
            //调用 join 方法，将拆分任务执行完的结果进行汇总
            result = myTask1.join() + myTask2.join();
        }
        //将结果返回
        return result;
    }
}
